package com.learn.rpc.version.version5;

import com.learn.rpc.common.AdminUser;
import com.learn.rpc.common.AdminUserServiceImpl;
import com.learn.rpc.common.FinalParam;
import com.learn.rpc.common.IAdminUserService;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Objects;

/**
 * @author wangxing
 * @version 2020/8/15 7:03 Administrator
 */
public class RpcServer {
    static boolean running = true;

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(FinalParam.PORT);
        while (running){
            try {
                Socket accept = serverSocket.accept();
                process(accept);
                accept.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    private static void process(Socket socket) throws IOException, ClassNotFoundException, NoSuchMethodException,
            IllegalAccessException, InstantiationException, InvocationTargetException {
        ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());

        String className = inputStream.readUTF();
        String methodName = inputStream.readUTF();
        Class[] paramsTypes = (Class[]) inputStream.readObject();
        Object[] args = (Object[]) inputStream.readObject();
        Class clazz = getClassInterfaces(className);
        Method method = clazz.getMethod(methodName, paramsTypes);
        Object invoke = method.invoke(clazz.newInstance(), args);

        ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
        outputStream.writeObject(invoke);
        outputStream.flush();
        outputStream.close();
        inputStream.close();
    }

    private static Class getClassInterfaces(String className) {
        if(Objects.equals(className, IAdminUserService.class.getName())){
            return AdminUserServiceImpl.class;
        }
        return null;
    }


}
